<template>
  <div id='chart' class="chart"></div>
</template>
<script>
import * as d3 from 'd3';
export default {
  name: 'chart',
  data() {
    return {
      relationArr: [
        {
          source: 'F8052',
          target: 'F8404'
        },
        {
          source: 'F8052',
          target: 'F8253'
        },
        {
          source: 'F8085',
          target: 'F8253'
        },
        {
          source: 'F8085',
          target: 'F8070'
        },
        {
          source: 'F8085',
          target: 'F8060'
        },
        {
          source: 'F8085',
          target: 'F8212'
        },
        {
          source: 'F8085',
          target: 'F8253'
        },
        {
          source: 'F8085',
          target: 'F8213'
        },
        {
          source: 'F8087',
          target: 'F8061'
        },
        {
          source: 'F8094',
          target: 'F8095'
        },
        {
          source: 'F8094',
          target: 'F8204'
        },
        {
          source: 'F8095',
          target: 'F8253'
        },
        {
          source: 'F8102',
          target: 'F8061'
        },
        {
          source: 'F8104',
          target: 'F8253'
        },
        {
          source: 'F8106',
          target: 'F8272'
        },
        {
          source: 'F8106',
          target: 'F8208'
        },
        {
          source: 'F8106',
          target: 'F8110'
        },
        {
          source: 'F8108',
          target: 'F8272'
        },
        {
          source: 'F8112',
          target: 'F8404'
        },
        {
          source: 'F8118',
          target: 'F8117'
        },
        {
          source: 'F8119',
          target: 'F8060'
        },
        {
          source: 'F8119',
          target: 'F8070'
        },
        {
          source: 'F8119',
          target: 'F8225'
        },
        {
          source: 'F8200',
          target: 'F8253'
        },
        {
          source: 'F8201',
          target: 'F8060'
        },
        {
          source: 'F8201',
          target: 'F8213'
        },
        {
          source: 'F8208',
          target: 'F8253'
        },
        {
          source: 'F8208',
          target: 'F8040'
        },
        {
          source: 'F8209',
          target: 'F8272'
        },
        {
          source: 'F8219',
          target: 'F8253'
        },
        {
          source: 'F8226',
          target: 'F8404'
        },
        {
          source: 'F8226',
          target: 'F8253'
        },
        {
          source: 'F8231',
          target: 'F8110'
        },
        {
          source: 'F8231',
          target: 'F8272'
        },
        {
          source: 'F8231',
          target: 'F8040'
        },
        {
          source: 'F8234',
          target: 'F8272'
        },
        {
          source: 'F8237',
          target: 'F8027'
        },
        {
          source: 'F8239',
          target: 'F8208'
        },
        {
          source: 'F8239',
          target: 'F8253'
        },
        {
          source: 'F8240',
          target: 'F8404'
        },
        {
          source: 'F8241',
          target: 'F8404'
        },
        {
          source: 'F8249',
          target: 'F8259'
        },
        {
          source: 'F8250',
          target: 'F8253'
        },
        {
          source: 'F8252',
          target: 'F8253'
        },
        {
          source: 'F8253',
          target: 'F8310'
        },
        {
          source: 'F8253',
          target: 'F8350'
        },
        {
          source: 'F8253',
          target: 'F8212'
        },
        {
          source: 'F8253',
          target: 'F8213'
        },
        {
          source: 'F8253',
          target: 'F8404'
        },
        {
          source: 'F8253',
          target: 'F8070'
        },
        {
          source: 'F8254',
          target: 'F8404'
        },
        {
          source: 'F8259',
          target: 'F8060'
        },
        {
          source: 'F8260',
          target: 'F8259'
        },
        {
          source: 'F8261',
          target: 'F8259'
        },
        {
          source: 'F8262',
          target: 'F8259'
        },
        {
          source: 'F8263',
          target: 'F8259'
        },
        {
          source: 'F8264',
          target: 'F8259'
        },
        {
          source: 'F8265',
          target: 'F8259'
        },
        {
          source: 'F8266',
          target: 'F8270'
        },
        {
          source: 'F8266',
          target: 'F8268'
        },
        {
          source: 'F8266',
          target: 'F8267'
        },
        {
          source: 'F8270',
          target: 'F8208'
        },
        {
          source: 'F8270',
          target: 'F8272'
        },
        {
          source: 'F8272',
          target: 'F8313'
        },
        {
          source: 'F8272',
          target: 'F8314'
        },
        {
          source: 'F8272',
          target: 'F8396'
        },
        {
          source: 'F8272',
          target: 'F8397'
        },
        {
          source: 'F8272',
          target: 'F8398'
        },
        {
          source: 'F8272',
          target: 'F8400'
        },
        {
          source: 'F8272',
          target: 'F8315'
        },
        {
          source: 'F8272',
          target: 'F8406'
        },
        {
          source: 'F8272',
          target: 'F8316'
        },
        {
          source: 'F8272',
          target: 'F8317'
        },
        {
          source: 'F8272',
          target: 'F8312'
        },
        {
          source: 'F8272',
          target: 'F8311'
        },
        {
          source: 'F8272',
          target: 'F8355'
        },
        {
          source: 'F8272',
          target: 'F8354'
        },
        {
          source: 'F8272',
          target: 'F8274'
        },
        {
          source: 'F8272',
          target: 'F8273'
        },
        {
          source: 'F8278',
          target: 'F8299'
        },
        {
          source: 'F8278',
          target: 'F8255'
        },
        {
          source: 'F8278',
          target: 'F8300'
        },
        {
          source: 'F8278',
          target: 'F8301'
        },
        {
          source: 'F8278',
          target: 'F8111'
        },
        {
          source: 'F8278',
          target: 'F8360'
        },
        {
          source: 'F8278',
          target: 'F8281'
        },
        {
          source: 'F8278',
          target: 'F8280'
        },
        {
          source: 'F8278',
          target: 'F8279'
        },
        {
          source: 'F8278',
          target: 'F8320'
        },
        {
          source: 'F8310',
          target: 'F8404'
        },
        {
          source: 'F8358',
          target: 'F8279'
        },
        {
          source: 'F8358',
          target: 'F8280'
        },
        {
          source: 'F8358',
          target: 'F8281'
        },
        {
          source: 'F8358',
          target: 'F8111'
        },
        {
          source: 'F8358',
          target: 'F8299'
        },
        {
          source: 'F8358',
          target: 'F8255'
        },
        {
          source: 'F8358',
          target: 'F8300'
        },
        {
          source: 'F8358',
          target: 'F8301'
        },
        {
          source: 'F8358',
          target: 'F8320'
        },
        {
          source: 'F8358',
          target: 'F8360'
        },
        {
          source: 'F8362',
          target: 'F8060'
        },
        {
          source: 'F8362',
          target: 'F8370'
        },
        {
          source: 'F8362',
          target: 'F8253'
        },
        {
          source: 'F8372',
          target: 'F8399'
        },
        {
          source: 'F8372',
          target: 'F8411'
        },
        {
          source: 'F8372',
          target: 'F8378'
        },
        {
          source: 'F8372',
          target: 'F8377'
        },
        {
          source: 'F8372',
          target: 'F8376'
        },
        {
          source: 'F8372',
          target: 'F8374'
        },
        {
          source: 'F8372',
          target: 'F8375'
        },
        {
          source: 'F8379',
          target: 'F8381'
        },
        {
          source: 'F8379',
          target: 'F8380'
        },
        {
          source: 'F8379',
          target: 'F8383'
        },
        {
          source: 'F8379',
          target: 'F8382'
        },
        {
          source: 'F8385',
          target: 'F8253'
        },
        {
          source: 'F8385',
          target: 'F8408'
        },
        {
          source: 'F8385',
          target: 'F8409'
        },
        {
          source: 'F8395',
          target: 'F8406'
        },
        {
          source: 'F8395',
          target: 'F8400'
        },
        {
          source: 'F8395',
          target: 'F8398'
        },
        {
          source: 'F8395',
          target: 'F8397'
        },
        {
          source: 'F8395',
          target: 'F8396'
        },
        {
          source: 'F8395',
          target: 'F8274'
        },
        {
          source: 'F8404',
          target: 'F8070'
        },
        {
          source: 'F8405',
          target: 'F8060'
        },
        {
          source: 'F8405',
          target: 'F8404'
        },
        {
          source: 'F8405',
          target: 'F8253'
        },
        {
          source: 'F8407',
          target: 'F8253'
        },
        {
          source: 'F8412',
          target: 'F8419'
        },
        {
          source: 'F8412',
          target: 'F8415'
        },
        {
          source: 'F8412',
          target: 'F8414'
        },
        {
          source: 'F8412',
          target: 'F8418'
        },
        {
          source: 'F8412',
          target: 'F8417'
        },
        {
          source: 'F8412',
          target: 'F8416'
        },
        {
          source: 'F8412',
          target: 'F8413'
        },
        {
          source: 'F8422',
          target: 'F8070'
        },
        {
          source: 'F8422',
          target: 'F8201'
        },
        {
          source: 'F8422',
          target: 'F8253'
        }
      ],
      width: '',
      height: ''
    };
  },
  mounted: function() {
    this.$nextTick(function() {
      this.draw(this.relationArr);
    });
  },
  methods: {
    // 画图
    draw(edgelist) {
      var nodeHash = {};
      var edgeHash = {};
      var nodes = [];
      var edges = [];

      edgelist.forEach(function(edge, i) {
        if (!nodeHash[edge.source]) {
          nodeHash[edge.source] = { id: edge.source, label: edge.source };
          nodes.push(nodeHash[edge.source]);
        }
        if (!nodeHash[edge.target]) {
          nodeHash[edge.target] = { id: edge.target, label: edge.target };
          nodes.push(nodeHash[edge.target]);
        }
        edges.push({
          source: nodeHash[edge.source],
          target: nodeHash[edge.target],
          weight: 1,
          edgeNumber: 2
        });
      });
      this.createForceNetwork(nodes, edges);
    },
    createForceNetwork(nodes, edges) {
      var vm = this;
      var chart = document.getElementById('chart');
      vm.width = chart.clientWidth;
      vm.height = chart.clientHeight;
      var svg = d3
        .select('#chart')
        .append('svg')
        .attr('width', vm.width)
        .attr('height', vm.height);
      // 箭头
      var marker = svg
        .append('defs')
        .append('marker')
        .attr('id', 'Triangle')
        .attr('refX', 6)
        .attr('refY', 3)
        .attr('markerUnits', 'userSpaceOnUse')
        .attr('markerWidth', 6)
        .attr('markerHeight', 9)
        .attr('orient', 'auto')
        .append('path')
        .style('fill', '#dddddd')
        .attr('d', 'M 0 0 6 3 0 6 1.5 3');

      var sizeScale = d3.scale
        .linear()
        .domain([1, 20])
        .range([20, 40]);

      var force = d3.layout
        .force()
        .nodes(nodes)
        .links(edges)
        .size([vm.width, vm.height])
        .charge(function(d) {
          return d.weight * -100;
        })
        .linkDistance(80)
        .gravity(0.05)
        .on('tick', ticked);

      var link = svg
        .append('g')
        .attr('class', 'link-all')
        .selectAll('line')
        .data(edges)
        .enter()
        .append('line')
        .style('stroke-width', '2px')
        .style('stroke', '#dddddd')
        .attr('marker-end', 'url(#Triangle)');

      var node = svg
        .append('g')
        .attr('class', 'node-all')
        .selectAll('g')
        .data(nodes)
        .enter()
        .append('g')
        .attr('class', 'node')
        .call(
          force.drag().on('dragstart', function(d) {
            return (d.fixed = true);
          })
        );

      node
        .append('circle')
        .attr('class', 'node')
        .style('fill', 'ddd')
        .style('stroke', 'gray')
        .style('stroke-width', '2px');

      var nodeText = node
        .append('text')
        .style('fill', '#0e1f3d')
        .style('text-anchor', 'middle')
        .text(function(d) {
          return d.id;
        });

      force.start();

      function ticked() {
        d3
          .select('svg')
          .selectAll('line')
          .each(function(d) {
            var startCoords = vm.offsetEdge(
              d,
              sizeScale(d.source.weight),
              sizeScale(d.target.weight)
            );
            d3
              .select(this)
              .attr('x1', startCoords.x1)
              .attr('y1', startCoords.y1)
              .attr('x2', startCoords.x2)
              .attr('y2', startCoords.y2);
          });

        d3
          .select('svg')
          .selectAll('circle.node')
          .attr('r', function(d) {
            return sizeScale(d.weight);
          });

        d3
          .select('svg')
          .selectAll('g.node')
          .attr('transform', function(d) {
            return 'translate(' + d.x + ',' + d.y + ')';
          });
      }
    },
    offsetEdge(d, sourceSize, targetSize) {
      var sourceCirc = sourceSize * 2 * Math.PI;
      var targetCirc = targetSize * 2 * Math.PI;
      var stRatio = sourceCirc / targetCirc;

      var diffX = d.target.y - d.source.y;
      var diffY = d.target.x - d.source.x;

      var angle0 = Math.atan2(diffY, diffX) + Math.PI / 2;
      var angle1 = angle0 + (Math.PI * 0.75 + d.edgeNumber * 0.25);
      var angle2 = angle0 + (Math.PI * 0.25 - d.edgeNumber * 0.25);

      var x1 = d.source.x + sourceSize * Math.cos(angle1);
      var y1 = d.source.y - sourceSize * Math.sin(angle1);
      var x2 = d.target.x + targetSize * Math.cos(angle2);
      var y2 = d.target.y - targetSize * Math.sin(angle2);

      return { x1: x1, y1: y1, x2: x2, y2: y2 };
    }
  }
};
</script>
<style lang="less">
.chart {
  width: 100%;
  height: 100%;
}
</style>